package controller;

import model.DataHolder;
import model.utils.Sounds;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.graphics.Point;
import android.graphics.Rect;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.FragmentActivity;
import android.view.Display;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.view.animation.DecelerateInterpolator;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.RelativeLayout.LayoutParams;

import com.example.towerdefence.R;

public class MenuActivity extends FragmentActivity {

	private static final int DALAY_TIME_FOR_DOOR_OPENING = 200;
	private static final int DALAY_TIME_FADE_AWAY = 1240;
	// The system "short" animation time duration, in milliseconds. This
	// duration is ideal for subtle animations or animations that occur
	// very frequently.
	private int mShortAnimationDuration;
	private int screenWidth;
	private int screenHeight;

	@SuppressLint("CutPasteId")
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setFullScreen();

		Sounds.setInstanceOfSounds(this);
		Sounds.playSoundOnMenu();
		// Starting the layout menu_activity
		setContentView(R.layout.menu_activity);
		setScreenWidthAndHeight();
		// Setting the start button
		Button startBtn = (Button) findViewById(R.id.startbtn);

		LayoutParams params = new RelativeLayout.LayoutParams(
				LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);

		// Checking screen resolution to see where to place startbtn
		if (screenWidth > 1200) {
			// Setting start button for tablet to be in the middle of the door
			params.setMargins((int) (screenWidth / 2.335),
					(int) (screenHeight / 1.5), 0, 0);
		} else {
			// Setting start button for phone to be in the middle of the door
			params.setMargins((int) (screenWidth / 2.51),
					(int) (screenHeight / 1.6), 0, 0);
		}

		// Hook up clicks on the startbtn.
		startBtn.setLayoutParams(params);

		final View startbtn = findViewById(R.id.startbtn);
		startbtn.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View view) {
				DataHolder.clearData();
				// When the start button is clicked, it becomes invisible and
				// the animation starts
				startbtn.setVisibility(View.GONE);

				// Stopping sound after the button is clicked

				// Zoom in animation begins

				animationBackground();

				// Delay for zooming animation
				final Handler handler1 = new Handler();
				handler1.postDelayed(new Runnable() {

					public void run() {
						// Starting music before game starts for fade away
						// screen
						Sounds.stopSoundOnMenu();
						MediaPlayer m1Player = MediaPlayer.create(
								MenuActivity.this, R.raw.testfadeaway);
						m1Player.start();
						// Starting the zoomImage method when the start button
						// is clicked with a delay
						zoomImage(startbtn, R.drawable.zoomedcastledoor);
					}
				}, 2040);

				handler1.postDelayed(new Runnable() {
					public void run() {
						// Starting the fading screen before the main activity
						// starts, with delay
						fadeScreenBeforeMainActivity();

					}
				}, 4040);

				handler1.postDelayed(new Runnable() {
					public void run() {
						// Starting the main activity of the game after all the
						// other delayes
						Intent myIntent = new Intent(MenuActivity.this,
								GameBoardActivity.class);
						MenuActivity.this.startActivity(myIntent);
						finish();
					}
				}, 6840);
			}
		});

		// Hooking up the quit button
		final Button quitbtn = (Button) findViewById(R.id.quitbtn);
		quitbtn.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View view) {
				// Making the quit button kill the process and close everything
				android.os.Process.killProcess(android.os.Process.myPid());
				System.exit(0);
			}
		});

		// Retrieve and cache the system's default "short" animation time.
		// Making the animation "short"
		mShortAnimationDuration = getResources().getInteger(
				android.R.integer.config_shortAnimTime);
	}

	/**
	 * @param thumbView
	 * @param imageResId
	 *            Making the animation zoom in the opened door, after the start
	 *            button is clicked
	 */
	private void zoomImage(final View thumbView, int imageResId) {
		// Load the high-resolution "zoomed-in" image.
		final ImageView expandedImageView = (ImageView) findViewById(R.id.expanded_image);
		expandedImageView.setImageResource(imageResId);

		// Calculate the starting and ending bounds for the zoomed-in image.
		final Rect startBounds = new Rect();
		final Rect finalBounds = new Rect();
		final Point globalOffset = new Point();

		// The start bounds are the global visible rectangle of the start btn,
		// and the final bounds are the global visible rectangle of the
		// container
		// view. Also set the container view's offset as the origin for the
		// bounds, since that's the origin for the positioning animation
		// properties (X, Y).
		thumbView.getGlobalVisibleRect(startBounds);
		findViewById(R.id.container).getGlobalVisibleRect(finalBounds,
				globalOffset);
		startBounds.offset(-globalOffset.x, -globalOffset.y);
		finalBounds.offset(-globalOffset.x, -globalOffset.y);

		// Adjust the start bounds to be the same aspect ratio as the final
		// bounds using the "center crop" technique. This prevents undesirable
		// stretching during the animation. Also calculate the start scaling
		// factor (the end scaling factor is always 1.0).
		float startScale;
		if ((float) finalBounds.width() / finalBounds.height() > (float) startBounds
				.width() / startBounds.height()) {
			// Extend start bounds horizontally
			startScale = (float) startBounds.height() / finalBounds.height();
			float startWidth = startScale * finalBounds.width();
			float deltaWidth = (startWidth - startBounds.width()) / 2;
			startBounds.left -= deltaWidth;
			startBounds.right += deltaWidth;
		} else {
			// Extend start bounds vertically
			startScale = (float) startBounds.width() / finalBounds.width();
			float startHeight = startScale * finalBounds.height();
			float deltaHeight = (startHeight - startBounds.height()) / 2;
			startBounds.top -= deltaHeight;
			startBounds.bottom += deltaHeight;
		}

		// Hide the start button and show the zoomed-in view. When the animation
		// begins, it will position the zoomed-in view in the place of the
		// start button.
		thumbView.setAlpha(0f);
		expandedImageView.setVisibility(View.VISIBLE);

		// Set the pivot point for SCALE_X and SCALE_Y transformations
		// to the top-left corner of the zoomed-in view (the default
		// is the center of the view).
		expandedImageView.setPivotX(0f);
		expandedImageView.setPivotY(0f);

		// Construct and run the parallel animation of the four translation and
		// scale properties (X, Y, SCALE_X, and SCALE_Y).
		AnimatorSet set = new AnimatorSet();
		set.play(
				ObjectAnimator.ofFloat(expandedImageView, View.X,
						startBounds.left, finalBounds.left))
				.with(ObjectAnimator.ofFloat(expandedImageView, View.Y,
						startBounds.top, finalBounds.top))
				.with(ObjectAnimator.ofFloat(expandedImageView, View.SCALE_X,
						startScale, 1f))
				.with(ObjectAnimator.ofFloat(expandedImageView, View.SCALE_Y,
						startScale, 1f));
		set.setDuration(mShortAnimationDuration);
		set.setInterpolator(new DecelerateInterpolator());
		set.addListener(new AnimatorListenerAdapter() {
			@Override
			public void onAnimationEnd(Animator animation) {
			}

			@Override
			public void onAnimationCancel(Animator animation) {
			}
		});
		set.start();
	}

	/**
	 * 
	 * Making fade screen animation for the menu when the start button is
	 * clicked while the main activity of the game is loading.
	 * 
	 */
	private void fadeScreenBeforeMainActivity() {

		final ImageView imageFadeAway = (ImageView) findViewById(R.id.expanded_image);
		// Making a handler for the delay of the animation
		final Handler handler = new Handler();
		// Giving delay to every picture of the animation with a for loop
		// and switch case so that it can change the picture every 200
		// miliseconds
		for (int i = 0; i < 8; i++) {
			final int b = i;
			switch (b) {
			case 0:
				handler.postDelayed(new Runnable() {
					public void run() {
						imageFadeAway
								.setImageResource(R.drawable.zoomedcastledoor1fadeaway);
					}
				}, DALAY_TIME_FADE_AWAY);
				break;
			case 1:
				handler.postDelayed(new Runnable() {
					public void run() {
						imageFadeAway
								.setImageResource(R.drawable.zoomedcastledoor2fadeaway);
					}
				}, DALAY_TIME_FADE_AWAY + 200);
				break;
			case 2:
				handler.postDelayed(new Runnable() {
					public void run() {
						imageFadeAway
								.setImageResource(R.drawable.zoomedcastledoor3fadeaway);
					}
				}, DALAY_TIME_FADE_AWAY + 400);
				break;
			case 3:
				handler.postDelayed(new Runnable() {
					public void run() {
						imageFadeAway
								.setImageResource(R.drawable.zoomedcastledoor4fadeaway);
					}
				}, DALAY_TIME_FADE_AWAY + 600);
				break;
			case 4:
				handler.postDelayed(new Runnable() {
					public void run() {
						imageFadeAway
								.setImageResource(R.drawable.zoomedcastledoor5fadeaway);
					}
				}, DALAY_TIME_FADE_AWAY + 800);
				break;
			case 5:
				handler.postDelayed(new Runnable() {
					public void run() {
						imageFadeAway
								.setImageResource(R.drawable.zoomedcastledoor6fadeaway);
					}
				}, DALAY_TIME_FADE_AWAY + 1000);
				break;
			case 6:
				handler.postDelayed(new Runnable() {
					public void run() {
						imageFadeAway
								.setImageResource(R.drawable.zoomedcastledoor7fadeaway);
					}
				}, DALAY_TIME_FADE_AWAY + 1200);
				break;
			case 7:
				handler.postDelayed(new Runnable() {
					public void run() {
						imageFadeAway
								.setImageResource(R.drawable.zoomedcastledoorblackfadeaway);
					}
				}, DALAY_TIME_FADE_AWAY + 1400);
				break;
			}
		}
	}

	/**
	 * Getting the screen resolution so that later we can check and put the
	 * buttons on places depending on the screen
	 */
	private void setScreenWidthAndHeight() {
		Display display = getWindowManager().getDefaultDisplay();
		Point size = new Point();
		display.getSize(size);
		screenWidth = size.x;
		screenHeight = size.y;
	}

	/**
	 * Making the animation - opening of the door and setting different delay on
	 * the pictures.
	 */
	private void animationBackground() {

		final RelativeLayout RLayout = (RelativeLayout) findViewById(R.id.container);
		final Handler handler = new Handler();

		// Giving delay to every picture of the animation with a for loop
		// and switch case
		for (int i = 0; i < 4; i++) {
			final int b = i;
			switch (b) {
			case 0:
				handler.postDelayed(new Runnable() {
					public void run() {
						RLayout.setBackgroundResource(R.drawable.animationdoor1);
					}
				}, DALAY_TIME_FOR_DOOR_OPENING);
				break;
			case 1:
				handler.postDelayed(new Runnable() {

					public void run() {
						RLayout.setBackgroundResource(R.drawable.animationdoor2);
					}
				}, DALAY_TIME_FOR_DOOR_OPENING + 200);
				break;
			case 2:
				handler.postDelayed(new Runnable() {
					public void run() {
						RLayout.setBackgroundResource(R.drawable.animationdoor3);
					}
				}, DALAY_TIME_FOR_DOOR_OPENING + 400);
				break;
			case 3:
				handler.postDelayed(new Runnable() {
					public void run() {
						RLayout.setBackgroundResource(R.drawable.opendoorbg);
					}
				}, DALAY_TIME_FOR_DOOR_OPENING + 600);
				break;
			}
		}
	}

	private void setFullScreen() {
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
				WindowManager.LayoutParams.FLAG_FULLSCREEN);
	}

	@Override
	protected void onPause() {
		super.onPause();
		Sounds.pauseSoundOnMenu();
		finish();
	}

	@Override
	protected void onResume() {
		super.onResume();
		Sounds.playSoundOnMenu();
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		finish();
		DataHolder.clearData();
	}
}